
package com.haiyou.common.util.network;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import lombok.extern.slf4j.Slf4j;

/**
 * 根据IP地址获取详细的地域信息
 */
@Slf4j
public class AddressUtils {

	static private final InetAddress addr;
	static {
		addr = getInetAddress();
	}

	public static String getHostAddress() {

		return addr.getHostAddress();
	}

	public static InetAddress getInetAddress() {
		try {
			InetAddress candidateAddress = null;
			// 遍历所有的网络接口
			for (Enumeration ifaces = NetworkInterface.getNetworkInterfaces(); ifaces.hasMoreElements();) {
				NetworkInterface iface = (NetworkInterface) ifaces.nextElement();
				// 在所有的接口下再遍历IP
				for (Enumeration inetAddrs = iface.getInetAddresses(); inetAddrs.hasMoreElements();) {
					InetAddress inetAddr = (InetAddress) inetAddrs.nextElement();
					if (!inetAddr.isLoopbackAddress()) {// 排除loopback类型地址
						if (inetAddr.isSiteLocalAddress()) {
							// 如果是site-local地址，就是它了
							return inetAddr;
						} else if (candidateAddress == null) {
							// site-local类型的地址未被发现，先记录候选地址
							candidateAddress = inetAddr;
						}
					}
				}
			}
			if (candidateAddress != null) {
				return candidateAddress;
			}
			// 如果没有发现 non-loopback地址.只能用最次选的方案
			InetAddress jdkSuppliedAddress = InetAddress.getLocalHost();
			return jdkSuppliedAddress;
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return null;
		}
	}

	/**
	 * 判断ip地址格式是否合法
	 *
	 * @param ip ip地址
	 * @return
	 */
	public static boolean validateIPFormat(String ip) {
		Pattern pattern = Pattern.compile("(\\d{1,3}\\.){3}\\d{1,3}");
		Matcher matcher = pattern.matcher(ip);
		if (!matcher.find())
			return false;
		String[] temp = ip.split("\\.");
		if (temp.length != 4)
			return false;
		for (int i = 0; i < temp.length; i++) {
			int mask = Integer.parseInt(temp[i]);
			if (mask < 0 || mask > 255)
				return false;
			if (i == 0 && mask == 0)
				return false;
			if (i == 3 && mask == 0)
				return false;
		}
		return true;
	}

}
